/**
 * Class:	ReferencesController
 * 
 * Variables:
 * 
 * 		accessibility type variableName;
 * 		(e.g. "private List<String> beneficiaries;")
 * 
 * Remarks:
 * 
 * 		Kindly list only only accessible variables:
 * 			> non-private variables ( public, protected,
 * 			  default )
 * 			> private variables with getters and/or
 * 			  setters 
 * 		
 * 		Variables are set to private and can be accessed
 * 		only through their getters and setters.
 * 		
 * 		In this controller, one can add, view, update
 * 		and delete Organizations.
 * 
 * @author ( your name )
 * @version ( 2013-02-28 // YYYY-MM-DD )
 */

package controllers;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.JOptionPane;

import managers.OrganizationManager;
import managers.VolunteerActivityManager;

import models.Organization;
import models.VolunteerActivity;

import views.ReferencesView;

public class ReferencesController extends AbstractController {
	
	/* Instance Variables */
	private ReferencesView referencesView;
	private ArrayList<Organization> organizationList;
	private Organization chosenOrganization;
	
	
	
	/**
	 * Constructors
	 */
	
	public ReferencesController( ReferencesView referencesView ) {
		super();
		this.referencesView = referencesView;
		chosenOrganization = null;
		refreshTable();
		setupReferencesView();
	}
	
	
	
	/**
	 * Add Organization
	 *		- allows the user to add an organization
	 *		- initializes the Views, or portions
	 *		  of Views, for adding an organization
	 * 
	 * Parameter
	 *		- n/a
	 *	
	 * Returns
	 *		- n/a
	 */
	public void addOrganization() {
		boolean active = false;
		
		if ( referencesView.cmbStatus.getSelectedItem().equals( "Active" ) ) {
			active = true;
		}
		
		Organization organization = new Organization( referencesView.txtName.getText(),
													  referencesView.txtType.getText(),
													  active );
		
		if ( organizationExists( organization ) ) {
			JOptionPane.showMessageDialog( referencesView, "Organization already exists! Please set any" +
										   " disbanded organizations as \"Inactive.\"",
										   "Error!", JOptionPane.ERROR_MESSAGE );
			return;
		}
		
		if ( new OrganizationManager().insertOrganization( organization ) ) {
			if ( confirmationMessages.isOperationSuccess() ) {
				JOptionPane.showMessageDialog( referencesView, "Organization successfully added!",
											   "Success!", JOptionPane.PLAIN_MESSAGE );
			}
		}
		else {
			JOptionPane.showMessageDialog( referencesView, "Could not add the organization into the database.",
										   "Error!", JOptionPane.ERROR_MESSAGE );
		}
	}
	
	
	
	/**
	 * Update Organization
	 *		- allows the user to update an
	 *		  organization
	 *		- initializes the Views, or portions
	 *		  of Views, for updating an organization
	 * 
	 * Parameter
	 *		- n/a
	 *	
	 * Returns
	 *		- n/a
	 */
	public void updateOrganization() {
		boolean active = false;
		
		if ( referencesView.cmbStatus.getSelectedItem().equals( "Active" ) ) {
			active = true;
		}
		
		Organization organization = new Organization( referencesView.txtName.getText(),
													  referencesView.txtType.getText(),
													  active );
		
		if ( organizationExists( organization ) ) {
			JOptionPane.showMessageDialog( referencesView, "Organization already exists! Please set any" +
					   " disbanded organizations as \"Inactive.\"",
					   "Error!", JOptionPane.ERROR_MESSAGE );
			return;
		}
		
		if ( new OrganizationManager().updateOrganization( chosenOrganization, organization ) ) {
			if ( confirmationMessages.isOperationSuccess() ) {
				JOptionPane.showMessageDialog( referencesView, "Organization successfully updated!",
											   "Success!", JOptionPane.PLAIN_MESSAGE );
			}
		}
		else {
			JOptionPane.showMessageDialog( referencesView, "Could not update the organization.",
										   "Error!", JOptionPane.ERROR_MESSAGE );
		}
	}
	
	
	
	/**
	 * Set Up ReferencesView
	 *		- sets up the references view action listeners
	 *		
	 * Parameter
	 *		- n/a
	 *	
	 * Returns
	 *		- n/a
	 */
	private void setupReferencesView() {
		referencesView.btnAddOrganization.addActionListener( new ActionListener() {
			public void actionPerformed( ActionEvent event ) {
				setupAddOrganization();
			}
		});
		
		referencesView.btnUpdateOrganization.addActionListener( new ActionListener() {
			public void actionPerformed( ActionEvent event ) {
				if ( referencesView.tblOrganizations.getSelectedRow() > -1 ) {
					setupUpdateOrganization();
				}
				else {
					JOptionPane.showMessageDialog( referencesView, "Please select an organization.",
												   "Error!", JOptionPane.ERROR_MESSAGE );
				}
			}
		});
	}
	
	
	
	/**
	 * Set Up Add Organization
	 *		- sets up the add organization view and action listeners
	 *		
	 * Parameter
	 *		- n/a
	 *	
	 * Returns
	 *		- n/a
	 */
	private void setupAddOrganization() {
		referencesView.scpAddUpdate.setVisible( true );
		referencesView.lblAddupdateOrganization.setText( "Add Organization" );
		
		referencesView.btnCancel.addActionListener( new ActionListener() {
			public void actionPerformed( ActionEvent event ) {
				removePanel();
			}
		});
		
		referencesView.btnSave.addActionListener( new ActionListener() {
			public void actionPerformed( ActionEvent event ) {
				if ( !inputHasError() ) {
					addOrganization();
					removePanel();
					refreshTable();
				}
			}
		});
	}
	
	
	
	/**
	 * Set Up Update Organization
	 *		- sets up the update organization view and action listeners
	 *		
	 * Parameter
	 *		- n/a
	 *	
	 * Returns
	 *		- n/a
	 */
	private void setupUpdateOrganization() {
		referencesView.scpAddUpdate.setVisible( true );
		referencesView.lblAddupdateOrganization.setText( "Update Organization" );
		
		chosenOrganization = organizationList.get( referencesView.tblOrganizations.getSelectedRow() );
		referencesView.txtName.setText( chosenOrganization.getName() );
		referencesView.txtType.setText( chosenOrganization.getType() );
		
		if ( chosenOrganization.isActive() ) {
			referencesView.cmbStatus.setSelectedIndex( 0 );
		}
		else {
			referencesView.cmbStatus.setSelectedIndex( 1 );
		}
		
		referencesView.btnCancel.addActionListener(new ActionListener() {
			public void actionPerformed( ActionEvent event ) {
				referencesView.scpAddUpdate.setVisible(false);
				removePanel();
			}
		});
		
		referencesView.btnSave.addActionListener(new ActionListener() {
			public void actionPerformed( ActionEvent event ) {
				if ( !inputHasError() ) {
					updateOrganization();
					removePanel();
					refreshTable();
				}
			}
		});
	}
	
	
	
	/**
	 * Organization Exists
	 *		- checks if the organization already exists 
	 * 
	 * Parameter
	 *		- n/a
	 *	
	 * Returns
	 *		- n/a
	 */
	private boolean organizationExists( Organization newOrganization ) {
		for ( Organization organization : organizationList ) {
			if ( newOrganization.getName().equals( organization.getName() ) &&
				 newOrganization.getType().equals( organization.getType() ) &&
				 newOrganization.isActive() == organization.isActive() ) {
				
				return true;
			}
		}
		
		return false;
	}
	
	
	
	/**
	 * Input Has Error 
	 *		- checks the add / update panel for errors
	 *		
	 * Parameter
	 *		- n/a
	 *	
	 * Returns
	 *		- n/a
	 */
	private boolean inputHasError() {
		boolean error = false;
		
		if ( referencesView.txtName.getText().equals( "" ) ) {
			
			JOptionPane.showMessageDialog( referencesView, "Please give the organization a name.",
										   "Error!", JOptionPane.ERROR_MESSAGE );
			
			error = true;
		}
		
		if ( referencesView.txtType.getText().equals( "" ) ) {
			
			JOptionPane.showMessageDialog( referencesView, "Please give the organization a type.",
										   "Error!", JOptionPane.ERROR_MESSAGE );
			
			error = true;
		}
		
		return error;
	}
	
	
	
	/**
	 * Remove Panel
	 *		- removes the add / update panel
	 *		
	 * Parameter
	 *		- n/a
	 *	
	 * Returns
	 *		- n/a
	 */
	private void removePanel() {
		referencesView.txtName.setText( "" );
		referencesView.txtType.setText( "" );
		referencesView.cmbStatus.setSelectedIndex( 0 );
		
		referencesView.btnCancel.removeActionListener( referencesView.btnCancel.getActionListeners()[0] );
		referencesView.btnSave.removeActionListener( referencesView.btnSave.getActionListeners()[0] );
		
		chosenOrganization = null;
		referencesView.scpAddUpdate.setVisible(false);
		refreshTable();
	}
	
	
	
	/**
	 * Refresh Table
	 *		- refeshes the organization table
	 *		
	 * Parameter
	 *		- n/a
	 *	
	 * Returns
	 *		- n/a
	 */
	private void refreshTable() {
		organizationList = new OrganizationManager().viewOrganization();
		
		while ( referencesView.tblModelOrganizations.getRowCount() > 0 ) {
			referencesView.tblModelOrganizations.removeRow( 0 );
		}
		
		for ( Organization organization : organizationList ) {
			String active = "Inactive";
			if ( organization.isActive() ) {
				active = "Active";
			}
			
			referencesView.tblModelOrganizations.addRow( new String[] { organization.getName(),
																		organization.getType(),
																		active } );
		}
	}
}
